<?php
/**
 * Created by PhpStorm.
 * User: whwyy
 * Date: 2018/11/8 0008
 * Time: 18:02
 */

namespace BeReborn\Service\Common;


use BeReborn\Annotation\Annotation;
use BeReborn\Database\Connection;
use BeReborn\Error\Logger;
use BeReborn\Event\Event;
use BeReborn\Route\Router;
use Exception;
use Swoole\Server;
use Swoole\Timer;
use BeReborn\Service\Base\ServerBase;

/**
 * Class ServerWorker
 * @package BeReborn\Server
 */
class ServerWorker extends ServerBase
{

    public $socketControllers = APP_PATH . '/app/Sockets';

    /**
     * @param Server $server
     * @param int $worker_id
     * @throws Exception
     */
    public function onWorkerError(Server $server, int $worker_id)
    {
        Timer::clearAll();

        Logger::clear();

        fire(ServerTask::AFTER_TASK);
        of(ServerTask::AFTER_TASK);

        \BeReborn::clearProcessId($server->worker_pid);


        Logger::write('The server error. at No.' . $worker_id);
    }

    /**
     * @param Server $server
     * @param int $worker_id
     * @throws Exception
     */
    public function onWorkerStop(Server $server, int $worker_id)
    {
        Timer::clearAll();

        Logger::clear();

        fire(ServerTask::AFTER_TASK);
        of(ServerTask::AFTER_TASK);

        \BeReborn::clearProcessId($server->worker_pid);

        Logger::write('The server stop. at No.' . $worker_id);
    }

    /**
     * @param Server $server
     * @param int $worker_id
     * @throws Exception
     */
    public function onWorkerExit(Server $server, int $worker_id)
    {
        Timer::clearAll();

        Logger::clear();

	    putenv('state=exit');

        fire(ServerTask::AFTER_TASK);
        of(ServerTask::AFTER_TASK);

        \BeReborn::clearProcessId($server->worker_pid);

        Logger::write('The server exit. at No.' . $worker_id);
    }

    /**
     * @param Server $server
     * @param int $worker_id
     *
     * @return mixed|void
     * @throws Exception
     */
    public function onWorkerStart(Server $server, $worker_id)
    {
        Logger::$worker_id = $worker_id;

        $socket = \BeReborn::$app->socket;

	    putenv('state=start');

	    \BeReborn::setProcessId($server->worker_pid);

        $get_name = $this->get_process_name($socket, $worker_id);
        if (!empty($get_name) && !\BeReborn::getPlatform()->isMac()) {
            swoole_set_process_name($get_name);
        }
        $this->setWorkerAction($socket, $worker_id);
    }

    /**
     * @param $worker_id
     * @param  $socket
     * @throws Exception
     */
    private function setWorkerAction($socket, $worker_id)
    {
        \BeReborn::setIsStart(true);
        try {
            fire('SERVER_BEFORE_WORKER');
            if ($worker_id >= $socket->settings['worker_num']) {
                return;
            }
            /** @var Router $router */
            $router = \BeReborn::getApp('router');
            $router->loader();

            /** @var Annotation $manager */
            $manager = \BeReborn::getApp('annotation');
            $manager->path = $this->socketControllers;
            $manager->namespace = 'App\\Sockets\\';
            $manager->scanningController();

        } catch (\Throwable $exception) {
            Logger::write($exception->getMessage(), 'worker');
            $this->error($exception->getMessage());
        }
    }


    /**
     * @param \BeReborn\Service\Http\Server $socket
     * @param $worker_id
     * @return string
     */
    private function get_process_name($socket, $worker_id)
    {
        $prefix = \BeReborn::$app->id;
        if ($worker_id >= $socket->settings['worker_num']) {
            return $prefix . '.task.' . $worker_id;
        } else {
            return $prefix . '.worker.' . $worker_id;
        }
    }

}
